<!--登录页面-->
<template>
    <div class="login">
        <el-form class="form" :model="model" :rules="rules" ref="loginForm">
            <h1 class="title">学生成绩管理系统</h1>
            <el-alert title="默认管理员账户 admin 密码 111111" type="warning" show-icon
                      style="margin-bottom: 10px"
                      :closable="false"/>
            <el-alert title="测试教师账户 test111 密码 111111" type="warning" show-icon
                      style="margin-bottom: 10px"
                      :closable="false"/>
            <el-alert title="测试学生账户 202220491301 密码 107010" type="warning" show-icon
                      style="margin-bottom: 10px"
                      :closable="false"/>
            <el-form-item prop="userName">
                <el-input class="text" v-model="model.userName" prefix-icon="User" clearable
                          :placeholder="$t('login.username')"/>
            </el-form-item>
            <el-form-item prop="password">
                <el-input class="text" v-model="model.password" prefix-icon="Lock" show-password clearable
                          :placeholder="$t('login.password')"/>
            </el-form-item>
            <el-form-item prop="captcha">
                <div class="captcha">
                    <el-input class="text" v-model="model.captcha" prefix-icon="Picture"
                              placeholder="请输入验证码"/>
                    <img :src="captchaSrc" @click="refreshCaptcha"/>
                </div>
            </el-form-item>
            <el-link style="display: flex;margin-top: -15px;margin-bottom:10px;"
                     @click="forgetShow">{{ $t('login.forgetPassword') }}
            </el-link>
            <el-form-item>
                <el-button :loading="loading" type="primary" class="btn" size="large" @click="submit">
                    {{ btnText }}
                </el-button>
            </el-form-item>
        </el-form>
    </div>
    <el-dialog v-model="dialogVisible" title="忘记密码" width="30%" draggable @close="handleDialogClose">
        <el-form label-width="80px" :model="form" :rules="ruleforget">
            <el-form-item label="账户" prop="username">
                <el-input v-model="form.username"/>
            </el-form-item>
            <el-form-item label="手机号" prop="mobile">
                <el-input v-model="form.mobile"/>
            </el-form-item>
            <el-form-item label="验证码" prop="code">
                <el-input v-model="form.code" style="width: 200px"/>
                <el-button type="primary" style="width: 35%;margin-left: 4%" @click="sendVerificationCode"
                           :disabled="countdown > 0">
                    {{ countdown > 0 ? countdown + 's后重新发送' : '发送验证码' }}
                </el-button>
            </el-form-item>
            <el-form-item>
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="primary" @click="handleSubmit">重置密码</el-button>
            </el-form-item>
        </el-form>

    </el-dialog>
    <div class="change-lang">
        <change-lang/>
    </div>
</template>

<script>
import {computed, defineComponent, getCurrentInstance, onMounted, reactive, ref, toRefs, watch} from 'vue'
import {GetValidateCode, Login, RestartSysUserPassword} from '@/api/login'
import {useRoute, useRouter} from 'vue-router'
import ChangeLang from '@/layout/components/Topbar/ChangeLang.vue'
import useLang from '@/i18n/useLang'
import {useApp} from '@/pinia/modules/app'
import {ElMessage} from "element-plus";
import {SendVerificationCode} from "@/api/sysUser";

export default defineComponent({
    components: {ChangeLang},
    name: 'login',
    setup() {
        const dialogVisible = ref(false)
        const forgetShow = () => {
            dialogVisible.value = true
        }
        // 表单数据模型
        const defaultForm = {
            username: '',
            mobile: '',
            code: '',
        }

        const form = ref({defaultForm}) // 使用 ref 包裹该对象
        const ruleforget = {
            username: [{required: true, message: '请输入账户', trigger: 'blur'}],
            mobile: [
                {required: true, message: '请输入手机号', trigger: 'blur'},
                {pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur'}
            ],
            code: [
                {required: true, message: '请输入验证码', trigger: 'blur'},
                {pattern: /^\d{6}$/, message: '请输入6位数字验证码', trigger: 'blur'}
            ]
        }
        // 处理关闭弹窗事件
        const handleDialogClose = () => {
            form.value = {...defaultForm}
        }
        // 发送验证码的方法
        const sendVerificationCode = async () => {
            if (!form.value.mobile) {
                ElMessage.error('请输入手机号')
                return;
            }
            const {code} = await SendVerificationCode(form.value.mobile);
            if (code !== 200) {
                ElMessage.error('验证码发送失败')
                return;
            }
            ElMessage.success('验证码已发送,5分钟内有效');
            // 开始倒计时
            startCountdown();
        };
        let countdown = ref(0);
        let timer = null;
        // 开始倒计时
        const startCountdown = () => {
            countdown.value = 60;
            timer = setInterval(() => {
                countdown.value--;
                if (countdown.value === 0) {
                    clearInterval(timer);
                }
            }, 1000);
        };

        // 处理忘记密码提交事件
        const handleSubmit = async () => {
            const {code} = await RestartSysUserPassword(form.value.username, form.value.mobile, form.value.code);
            if (code === 200) {
                ctx.$message.success({
                    message: '密码重置成功',
                    duration: 1000,
                })
                dialogVisible.value = false;
            } else {
                ctx.$message.success({
                    message: '没有此用户，请检查手机号',
                    duration: 1000,
                })
            }
        };

        const {proxy: ctx} = getCurrentInstance() // 可以把ctx当成vue2中的this
        const router = useRouter()
        const route = useRoute()
        const {lang} = useLang()
        watch(lang, () => {
            state.rules = getRules()
        })
        const getRules = () => ({
            userName: [{required: true, message: ctx.$t('login.rules-username'), trigger: 'blur'}],
            password: [
                {required: true, message: ctx.$t('login.rules-password'), trigger: 'blur'},
                {min: 6, max: 12, message: ctx.$t('login.rules-regpassword'), trigger: 'blur'},
            ],
            captcha: [{required: true, message: ctx.$t('login.rules-validate-code'), trigger: 'blur'}],
        })

        // onMounted钩子函数
        onMounted(() => {
            state.refreshCaptcha()
        })

        const state = reactive({
            model: {
                userName: 'admin',
                password: '111111',
                captcha: '',      // 用户输入的验证码
                codeKey: ''       // 后端返回的验证码key
            },
            rules: getRules(),
            loading: false,
            captchaSrc: "",
            refreshCaptcha: async () => {
                const {data} = await GetValidateCode();
                state.model.codeKey = data.codeKey
                state.captchaSrc = data.codeValue
            },
            btnText: computed(() =>
                state.loading ? ctx.$t('login.logining') : ctx.$t('login.login')
            ),
            loginForm: ref(null),
            submit: () => {
                if (state.loading) {
                    return
                }
                state.loginForm.validate(async valid => {
                    if (valid) {
                        state.loading = true
                        const {code, data, message} = await Login(state.model)
                        if (+code === 200) {
                            ctx.$message.success({
                                message: ctx.$t('login.loginsuccess'),
                                duration: 1000,
                            })
                            const targetPath = decodeURIComponent(route.query.redirect)
                            if (targetPath.startsWith('http')) {
                                // 如果是一个url地址
                                window.location.href = targetPath
                            } else if (targetPath.startsWith('/')) {
                                // 如果是内部路由地址
                                await router.push(targetPath)
                            } else if (targetPath === 'undefined') {
                                await router.push('/')    // 请求成功以后，进入到首页
                            }
                            useApp().initToken(data)
                        } else {
                            ctx.$message.error(message)
                        }
                        state.loading = false
                    }
                })
            },
        })

        return {
            ...toRefs(state),
            dialogVisible,
            forgetShow,
            form,
            ruleforget,
            handleDialogClose,
            handleSubmit,
            sendVerificationCode,
            countdown
        }
    },
})
</script>

<style lang="scss" scoped>
.login {
  transition: transform 1s;
  transform: scale(1);
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #2d3a4b;

  .form {
    width: 520px;
    max-width: 100%;
    padding: 0 24px;
    box-sizing: border-box;
    margin: 160px auto 0;

    :deep {
      .el-input__wrapper {
        box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1) inset;
        background: rgba(0, 0, 0, 0.1);
      }

      .el-input-group--append > .el-input__wrapper {
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
      }

      .el-input-group--prepend > .el-input__wrapper {
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
      }
    }

    .title {
      color: #fff;
      text-align: center;
      font-size: 24px;
      margin: 0 0 24px;
    }

    .text {
      font-size: 16px;

      :deep(.el-input__inner) {
        color: #fff;
        height: 48px;
        line-height: 48px;

        &::placeholder {
          color: rgba(255, 255, 255, 0.2);
        }
      }
    }

    .btn {
      width: 100%;
    }
  }
}

.captcha {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.captcha img {
  cursor: pointer;
  margin-left: 20px;
}

.change-lang {
  position: fixed;
  right: 20px;
  top: 20px;

  :deep {
    .change-lang {
      height: 24px;

      &:hover {
        background: none;
      }

      .icon {
        color: #fff;
      }
    }
  }
}
</style>